/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2019 Payara Foundation and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://github.com/payara/Payara/blob/main/LICENSE.txt
 * See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at legal/OPEN-SOURCE-LICENSE.txt.
 *
 * GPL Classpath Exception:
 * The Payara Foundation designates this particular file as subject to the "Classpath"
 * exception as provided by the Payara Foundation in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package fish.payara.samples.formauth;


import fish.payara.samples.CliCommands;
import fish.payara.samples.NotMicroCompatible;
import fish.payara.samples.PayaraArquillianTestRunner;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Arrays;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.test.api.ArquillianResource;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertEquals;

/**
 * Verifies that the {@code fish.payara.permittedFormBasedAuthHttpMethods} system property has an effect.
 */
@RunWith(PayaraArquillianTestRunner.class)
@NotMicroCompatible
public class PermittedFormBasedAuthHttpMethodsTest {

    @ArquillianResource
    private URL base;

    @Deployment(testable=false)
    public static WebArchive createDeployment() {
        return ShrinkWrap.createFromZipFile(WebArchive.class, new File("src/test/resources/formauth.war"));
    }

    @BeforeClass
    public static void setUp() throws Exception {
        addContainerSystemProperty("fish.payara.permittedFormBasedAuthHttpMethods", "POST");
    }

    @AfterClass
    public static void cleanUp() throws Exception {
        clearContainerSystemProperty("fish.payara.permittedFormBasedAuthHttpMethods", "POST");
    }

    @Test
    public void formAuthIsForbiddenForMethodsNotPermitted() throws Exception {
        assertFormAuthResponse(HttpURLConnection.HTTP_FORBIDDEN, "GET");
        assertFormAuthResponse(HttpURLConnection.HTTP_FORBIDDEN, "HEAD");
        assertFormAuthResponse(HttpURLConnection.HTTP_FORBIDDEN, "PUT");
    }

    @Test
    public void formAuthIsOkForMethodsPermitted() throws Exception {
        assertFormAuthResponse(HttpURLConnection.HTTP_OK, "POST");
    }

    private void assertFormAuthResponse(int expectedStatus, String usedHttpMethod)
            throws MalformedURLException, IOException, ProtocolException {
        URL url = new URL(base, "/formauth/j_security_check?j_username=foo&j_password=bar");
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod(usedHttpMethod);
        assertEquals(expectedStatus, connection.getResponseCode());
    }

    public static void addContainerSystemProperty(String key, String value) {
        CliCommands.payaraGlassFish(Arrays.asList("create-jvm-options", "-D" + key + "=\"" + value + "\""));
    }

    public static void clearContainerSystemProperty(String key, String value) {
        CliCommands.payaraGlassFish(Arrays.asList("delete-jvm-options", "-D" + key+ "=\"" + value + "\""));
    }
}
